﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SharpDiary.Core.ORMapping;
using SharpDiary.Core.Utility;

namespace SharpDiary.Diary
{
    public partial class DiaryViewer : UserControl
    {
        #region Fields & Properties

        private int _maxTitleLength = 20; //日记标题最多显示的字数。
        private Color _activeBackColor = Color.FromKnownColor(KnownColor.Info);
        private Pen _activeBorderPen = new Pen(Color.FromKnownColor(KnownColor.ActiveCaption), 2f);
        private Pen _bottomLinePen = new Pen(Color.FromArgb(192, 192, 192), 1f);
        private bool _readOnly = true;
        private DiaryInfo _diary;

        public DiaryInfo Diary
        {
            get { return _diary; }
            set
            {
                if (value == null) { return; }

                _diary = DiaryInfo.DecryptDiaryInfo(value);

                DisplayDiary(_diary);

                Modified = false;
            }
        }

        private bool _showDeleteButton = true;

        /// <summary>
        /// 获取或设置是否显示删除按钮。
        /// </summary>
        public bool ShowDeleteButton
        {
            get { return _showDeleteButton; }
            set
            {
                _showDeleteButton = value;
                btnRemove.Visible = value;
            }
        }

        /// <summary>
        /// 是否只读。
        /// </summary>
        public bool ReadOnly
        {
            get { return _readOnly; }
            set
            {
                _readOnly = value;
                richTextBoxContent.ReadOnly = value;
                btnSave.Visible = !_readOnly;
            }
        }

        private bool _isSelected = false;

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value == _isSelected) { return; }

                _isSelected = value;

                pnlToolBar.Visible = value;
                Invalidate();
            }
        }

        private bool _modified = false;

        /// <summary>
        /// 内容是否被修改。
        /// </summary>
        public bool Modified
        {
            get { return _modified; }
            set
            {
                if (value == _modified) { return; }

                _modified = value;

                btnSave.Enabled = _modified;

                //修改状态时，只显示创建日期
                if (value)
                {
                    lblDatetime.Text = _diary.CreatedDatetime.ToLocalTime().ToString();
                }

                if (!string.IsNullOrEmpty(_diary.Id))
                {
                    if (!_modified)
                    {
                        btnLogo.ImageOnNormal = imageListMain.Images[0];
                    }
                    else
                    {
                        //如果为新建，则不更改图示。
                        if (string.IsNullOrEmpty(_diary.Id))
                        {
                            btnLogo.ImageOnNormal = imageListMain.Images[2];

                            return;
                        }

                        btnLogo.ImageOnNormal = imageListMain.Images[1];
                    }
                }
                else
                {
                    btnLogo.ImageOnNormal = imageListMain.Images[2];
                }
            }
        }

        #endregion

        #region Constructors

        public DiaryViewer()
        {
            InitializeComponent();

            DoubleBuffered = true;
            ResizeRedraw = true;

            _bottomLinePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;

            if (_diary == null)
            {
                _diary = new DiaryInfo();
            }

            //设置所有子控件的 Enter 事件。
            foreach (Control control in this.Controls)
            {
                control.Enter += new EventHandler(DiaryViewer_Enter);
            }

            DisplayDiary(_diary);
        }

        #endregion

        public event EventHandler<SavedEventArgs> Saved;

        protected virtual void OnSaved(object sender, SavedEventArgs e)
        {
            if (Saved != null)
            {
                Saved(this, e);
            }
        }

        public event EventHandler<SelectedEventArgs> Selected;

        protected virtual void OnSelected(object sender, SelectedEventArgs e)
        {
            if (Selected != null)
            {
                Selected(this, e);
            }
        }

        /// <summary>
        /// 日记被删除后触发此事件。
        /// </summary>
        public event EventHandler<RemovedEventArgs> Removed;

        protected virtual void OnRemoved(object sender, RemovedEventArgs e)
        {
            if (Removed != null)
            {
                Removed(sender, e);
            }
        }

        /// <summary>
        /// 显示日记内容。
        /// </summary>
        /// <param name="text">日记内容</param>
        private void DisplayContent(string text)
        {
            if (text == null) { return; }

            richTextBoxContent.Text = text;
        }

        /// <summary>
        /// 显示日记信息。
        /// </summary>
        /// <param name="diaryInfo">日记信息</param>
        private void DisplayDiary(DiaryInfo diaryInfo)
        {
            if (!string.IsNullOrEmpty(diaryInfo.Id))
            {
                DisplayContent(_diary.Content);

                if (_modified)
                {
                    btnLogo.ImageOnNormal = imageListMain.Images[1];
                }
                else
                {
                    btnLogo.ImageOnNormal = imageListMain.Images[0];
                }
            }
            else
            {
                richTextBoxContent.Clear();
                btnLogo.ImageOnNormal = imageListMain.Images[2];
            }

            if (_diary.CreatedDatetime != _diary.UpdateDatetime)
            {
                lblDatetime.Text = string.Format("{0} (修改于 {1})",
                    _diary.CreatedDatetime.ToLocalTime().ToString(),
                    _diary.UpdateDatetime.ToLocalTime().ToString());
            }
            else
            {
                lblDatetime.Text = _diary.CreatedDatetime.ToLocalTime().ToString();
            }

            Modified = false;
        }

        /// <summary>
        /// 搜索日记内容是否匹配关键字，如匹配则返回 true, 否则返回 false。
        /// </summary>
        /// <param name="keyWord">关键字</param>
        /// <returns>是否匹配</returns>
        public bool Search(string keyWord)
        {
            if (string.IsNullOrEmpty(keyWord)) { return false; }

            return _diary.Content.IndexOf(keyWord, StringComparison.CurrentCultureIgnoreCase) != -1;
        }

        /// <summary>
        /// 将日记信息发送到指定 e-mail。
        /// </summary>
        /// <param name="toEmail">目标 e-mail</param>
        public void SendMailAsync(string toEmail)
        {
            if (_diary == null) { return; }

            MailSender sender = new MailSender(
                UserSettings.GetInstance().GetSettingValue("SmtpHost"),
                int.Parse(UserSettings.GetInstance().GetSettingValue("SmtpPort")),
                UserSettings.GetInstance().GetSettingValue("SmtpUerName"),
                UserSettings.GetInstance().GetSettingValue("SmtpPassword"),
                true);

            sender.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(sender_SendCompleted);
            btnSendToEmail.Enabled = false;

            try
            {
                sender.SendMailAsync(_diary, toEmail, toEmail);
            }
            catch (Exception ex)
            {
                btnSendToEmail.Enabled = true;
                MessageBoxHelper.ShowException(ex);
            }
        }

        protected virtual void sender_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            btnSendToEmail.Enabled = true;
            MessageBoxHelper.ShowMessage("发送成功。");
        }

        private void richTextBoxContent_Enter(object sender, EventArgs e)
        {
        }

        private void DiaryViewer_Leave(object sender, EventArgs e)
        {
            IsSelected = false;

            this.BackColor = Color.White;
            lineTop.Hide();
            lineBottom.Hide();

            foreach (Control control in this.Controls)
            {
                control.BackColor = Color.White;
            }

            Save();

            Modified = false;
        }

        /// <summary>
        /// 保存信息。
        /// </summary>
        public void Save()
        {
            if (_diary != null && string.IsNullOrEmpty(_diary.Id) && richTextBoxContent.Text.Trim().Length == 0)
            {
                this.Hide();
                return;
            }

            SavedEventArgs args = new SavedEventArgs();

            //如内容已修改，则自动保存。
            if (_diary != null && _modified)
            {
                _diary.Content = richTextBoxContent.Text;
                string clearContent = richTextBoxContent.Text.Trim();
                _diary.Title = (clearContent.Length < _maxTitleLength + 1 ?
                    clearContent.Substring(0, clearContent.Length) : clearContent.Substring(0, _maxTitleLength) + "...");
                _diary.UpdateDatetime = DateTime.Now;

                if (!string.IsNullOrEmpty(_diary.Id))
                {
                    //如果有内容，则更新
                    if (richTextBoxContent.Text.Trim().Length != 0)
                    {
                        //更新
                        DiaryInfo.Update<DiaryInfo>(_diary);

                        args.Action = SavingAction.Updated;

                    }
                    else //无内容，则删除
                    {
                        DiaryInfo.Remove<DiaryInfo>(_diary);
                    }
                }
                else
                {
                    if (richTextBoxContent.Text.Trim().Length != 0)
                    {
                        _diary.Id = Guid.NewGuid().ToString();
                        _diary.CreatedDatetime = DateTime.Now;
                        _diary.UpdateDatetime = DateTime.Now;

                        //新建
                        DiaryInfo.Create<DiaryInfo>(_diary);

                        args.Action = SavingAction.Created;
                    }
                    else
                    {
                        this.Hide();
                        return;
                    }
                }

                if (_diary.CreatedDatetime != _diary.UpdateDatetime)
                {
                    lblDatetime.Text = string.Format("{0} (修改于 {1})",
                        _diary.CreatedDatetime.ToLocalTime().ToString(),
                        _diary.UpdateDatetime.ToLocalTime().ToString());
                }
                else
                {
                    lblDatetime.Text = _diary.CreatedDatetime.ToLocalTime().ToString();
                }
            }

            Modified = false;

            OnSaved(this, args);
        }

        private void DiaryViewer_Enter(object sender, EventArgs e)
        {
            IsSelected = true;

            this.BackColor = _activeBackColor;
            lineTop.Show();
            lineBottom.Show();

            foreach (Control control in this.Controls)
            {
                control.BackColor = _activeBackColor;
            }

            SelectedEventArgs args = new SelectedEventArgs();
            args.SelectedDiaryViewer = this;
            OnSelected(this, args);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            if (_isSelected)
            {
                Rectangle rect = this.ClientRectangle;
                rect.Inflate(-3, -1);
                rect.Offset(2, 0);
                e.Graphics.DrawRectangle(_activeBorderPen, rect);

                //ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, Border3DStyle.Flat);
            }
            else
            {
                e.Graphics.DrawLine(_bottomLinePen, new Point(0, this.Height - 1), new Point(this.Width, this.Height - 1));
            }
        }

        /// <summary>
        /// 删除日记。
        /// </summary>
        private void ExecuteRemoveAction()
        {
            if (_diary == null) { return; }

            if (string.IsNullOrEmpty(_diary.Id) && this.richTextBoxContent.Text.Length == 0)
            {
                _modified = false;
                this.Hide();

                return;
            }

            if (MessageBoxHelper.ShowConfirmation("您确定要删除这篇日记吗?") == DialogResult.No) { return; }

            if (!string.IsNullOrEmpty(_diary.Id))
            {
                if (DiaryInfo.Remove<DiaryInfo>(_diary))
                {
                    this.Hide();

                    RemovedEventArgs rea = new RemovedEventArgs();
                    OnRemoved(this, rea);

                    return;
                }
                else
                {
                    MessageBoxHelper.ShowMessage("删除失败，请稍候再试。");
                }
            }
            else
            {
                _modified = false;
                this.Hide();
            }
        }

        private void richTextBoxContent_TextChanged(object sender, EventArgs e)
        {
            Modified = true;
        }

        private void btnLogo_MouseClick(object sender, MouseEventArgs e)
        {

        }

        private void richTextBoxContent_Leave(object sender, EventArgs e)
        {
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (!btnSave.Enabled) { return; }

            Save();
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            ExecuteRemoveAction();
        }

        private void btnSendToEmail_Click(object sender, EventArgs e)
        {
            if (_modified) { Save(); }

            SendMailAsync("SharpDiary.Diary@gmail.com");
        }
    }

    public class SavedEventArgs : EventArgs
    {
        private SavingAction _action;

        public SavingAction Action
        {
            get { return _action; }
            set { _action = value; }
        }

        public SavedEventArgs() { }
    }

    public class RemovedEventArgs : EventArgs
    {
        public RemovedEventArgs() { }
    }

    public class SelectedEventArgs : EventArgs
    {
        private DiaryViewer _selectedDiaryViewer;

        /// <summary>
        /// 被选中的日记。
        /// </summary>
        public DiaryViewer SelectedDiaryViewer
        {
            get { return _selectedDiaryViewer; }
            set { _selectedDiaryViewer = value; }
        }

        public SelectedEventArgs() { }
    }

    public enum SavingAction
    {
        /// <summary>
        /// 更新了日记。
        /// </summary>
        Updated = 0,

        /// <summary>
        /// 新创建的日记。
        /// </summary>
        Created
    }

    public class OnModifiedEventArgs : EventArgs
    {
        public OnModifiedEventArgs() { }
    }
}
